#include "myfunc.h"

#include <QStringList>
#include <QHostAddress>
#include <QDateTime>
#include <QDebug>

int PFunc::string2bytes(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
    for (int i = 0; i < nSrcLength; i += 2)
    {
        // 输出高4位
        if (*pSrc >= '0' && *pSrc <= '9')
            *pDst = ((*pSrc - '0') << 4);
        else
            *pDst = ((*pSrc - 'A' + 10) << 4);
        pSrc++;
        // 输出低4位
        if (*pSrc >= '0' && *pSrc <= '9')
            *pDst |= (*pSrc - '0');
        else
            *pDst |= (*pSrc - 'A' + 10);
        *pDst = ((*pDst)&0XFF);
        pSrc++;
        pDst++;
    }
    return (nSrcLength / 2);
};


int PFunc::bytes2string(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
    const char tab[] = "0123456789ABCDEF";    // 0x0-0xf的字符查找表
    for (int i = 0; i < nSrcLength; i++)
    {
        *pDst++ = tab[*pSrc >> 4];
        *pDst++ = tab[*pSrc & 0x0f];
        pSrc++;
    }
    *pDst = '\0';
    return nSrcLength * 2;
};

//CRC校验
unsigned int  PFunc::crc16(unsigned char *ptr, unsigned int len)
{
    unsigned int wcrc = 0XFFFF;//预置16位crc寄存器，初值全部为1
    unsigned char temp;//定义中间变量
    unsigned int i = 0, j = 0;//定义计数

    for (i = 0; i < len; i++)//循环计算每个数据
    {
        temp = *ptr & 0X00FF;//将八位数据与crc寄存器亦或
        ptr++;//指针地址增加，指向下个数据
        wcrc ^= temp;//将数据存入crc寄存器
        for (j = 0; j < 8; j++)//循环计算数据的
        {
            if (wcrc & 0X0001)//判断右移出的是不是1，如果是1则与多项式进行异或。
            {
                wcrc >>= 1;//先将数据右移一位
                wcrc ^= 0XA001;//与上面的多项式进行异或
            }
            else//如果不是1，则直接移出
            {
                wcrc >>= 1;//直接移出
            }
        }
    }
    temp = wcrc;//crc的值
    return wcrc;
};

int PFunc::code(const unsigned char *buff, const int len, unsigned char *outbuf)
{
    char ch = 0;
    int nLen = 0;
    unsigned char * buf = (unsigned char *)buff;
    for (int i = 0; i < len; i++, nLen++)
    {
        ch = buf[i];
        if ((buf[i] | 0x0f) == 0xff && i > 0 && i < (len - 1))
        {
            *outbuf++ = 0xf0 & buf[i];
            *outbuf++ = 0x0f & buf[i];
            nLen += 1;
        }
        else {
            *outbuf++ = ch;
        }
    }
    return nLen;
}

int PFunc::uncode(const unsigned char *buff, int len, unsigned char *outbuf)
{
    char ch = 0;
    int nLen = 0;
    unsigned char * buf = (unsigned char *)buff;
    for (int i = 0; i < len; i++, nLen++)
    {
        ch = buf[i];
        if (buf[i] == 0xf0)
        {
#ifdef _DEBUG
            if (i > len - 2)
                printf("Error!\r\n");
            if (buf[i + 1] > 0x0f)
                printf("Error!\r\n");
#endif
            ch = 0xf0 | buf[++i];
        }
        *outbuf++ = ch;
    }
    return nLen;
}

bool PFunc::ipCheck(QString ip_str)
{
    QHostAddress addip(ip_str);
    if(addip.isNull()){
        return false;
    }
    return true;
//    if (INADDR_NONE != inet_addr(ip_str.c_str())) {
//        return true;
//    }
//    return false;
};

long PFunc::ipToInt(QString ip_str)
{
    QHostAddress addip(ip_str);
    if(addip.isNull()){
        qDebug() << QString("ip format [%1] error,please check the file format and code!")
                    .arg(ip_str);
        return 0;
    }else{
        return addip.toIPv4Address();
    }
//    if (INADDR_NONE != inet_addr(ip_str.c_str())) {
//        return ntohl(inet_addr(ip_str.c_str()));
//    }
//    else {
//        return 0;
//    }
};

QString PFunc::intToIp(long ip_int)
{
    QHostAddress addip(ip_int);
    if(addip.isNull()){
        qDebug()<<QString("ipInt format [%1] error,please check the file format and code!")
                  .arg(ip_int);
        return "0.0.0.0";
    }else{
        return addip.toString();
    }

//    char ip[64] = { 0 };
//#ifdef WIN32
//    strcpy_s(ip, inet_ntoa(*(in_addr*)&ip_int));
//#else
//    strcpy(ip, inet_ntoa(*(in_addr*)&ip_int));
//#endif
//    return std::string(ip);
};


///////////////////////////////////////////////////////////////////////////////////////
ulong PFunc::getIPLFromStr(QString _ipStr)
{
   ulong _ipl = 0;
   QStringList ipl = _ipStr.split('.',QString::SkipEmptyParts);
   if(4==ipl.size()){
       uint ip1=ipl.at(0).toInt()<<24;
       uint ip2=ipl.at(1).toInt()<<16;
       uint ip3=ipl.at(2).toInt()<<8;
       uint ip4=ipl.at(3).toInt();
       _ipl = ip1+ip2+ip3+ip4;
   }
   return _ipl;
}

QString PFunc::getIPStrFromIPL(ulong _ipl)
{
    QString _ipStr = "127.0.0.1";

    uint ip1 = _ipl>>24;
    uint ip2 = (_ipl<<8)>>24;
    uint ip3 = (_ipl<<16)>>24;
    uint ip4 = (_ipl<<24)>>24;
    _ipStr = QString("%1.%2.%3.%4").arg(ip1).arg(ip2).arg(ip3).arg(ip4);
    return _ipStr;
}

QString PFunc::getCurrentTime()
{
    return QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
}
